import { resolveEventData, resolveRenderer, toast } from 'amis';
import { udp } from '@cscec/udp-ui';
import type { RenderOptions } from 'amis';
import React from 'react';

// 根据plugin配置events生成事件
function generateEvents(props: any, events: any[]) {
  const tmp: any = {};
  events?.forEach(({ eventName }) => {
    const en = `on${udp.firstCase(eventName)}`;
    tmp[en] = (async (e: any) => {
      const { dispatchEvent } = props;
      const originEvent = props[en];
      const rendererEvent = await dispatchEvent(
        eventName,
        resolveEventData(props, e),
      );
      if (rendererEvent?.prevented) {
        return;
      }
      if (typeof originEvent === 'function') {
        originEvent(e);
      }
    });
  });
  return tmp;
}

// 生成自定义组件的属性
export function generateProps(props: any, events: any[]) {
  const excludes = ['dispatchEvent', 'formItemValue', '$$editor'];
  const {
    useMobileUI, typeMapping, rootStore, $schema, $path, theme, onImageEnlarge, onAction,
    translate, setPrinstineValue, statusStore, formPristine, formItemDispatchEvent, renderFormItems,
    removeHook, addHook, onOpenDialog, _filteredOptions, onBulkChange, onQuery, controlWidth,
    formLabelAlign, formHorizontal, formMode, formStore, classPrefix, resolveDefinitions,
    type, regions, extend_props, store, topStore, formInited, classnames, formItem, getValue, setValue,
    ...payload
  } = props;

  const onEvents = generateEvents(payload, events);
  const p: any = {};
  Object.keys(payload).forEach((k) => {
    if (payload[k] !== undefined && !excludes.includes(k)) {
      p[k] = payload[k];
    }
  });

  return {
    ...p, ...extend_props, ...onEvents, store: store || topStore,
  };
}

// 获取amis的env
export function getAmisEnv(session: 'design' | 'render' | 'preview' = 'render', extraOptions: any = {}): RenderOptions {
  const env: RenderOptions = {
    theme: 'antd',
    session,
    fetcher: async (options) => {
      const {
        url = '', method = 'get', data, config,
      } = options;
      const httpRequest = udp.request as any;
      if (!httpRequest[method as any]) {
        toast.warning(`暂不支持 ${method} 方式的请求！`);
        return {
          status: 200,
          headers: config.headers || {},
        };
      }
      const tmpUrl = extraOptions.urlRoot ? `${extraOptions.urlRoot}${url.indexOf('/') === 0 ? '' : '/'}${url}` : url;
      // console.log('[debug] fetcher:', tmpUrl, data, config);
      const result = await httpRequest[method as any]({ url: tmpUrl, data, ...config });
      return {
        status: result.code,
        data: {
          ...result,
          status: result.code,
          msg: result.message,
          data: result.data,
        },
        headers: config.headers || {},
      };
    },
    useMobileUI: false,
    ...extraOptions,
  } as RenderOptions;
  if (session !== 'design') {
    env.rendererResolver = (path, schema) => {
      let Component: any;
      try {
        Component = schema.type ? require(`./componentAdapter/${schema.type}`).default : null;
      } catch {
        Component = null;
      }

      return Component ? { component: React.forwardRef((props, ref) => <Component {...props} outRef={ref} />) } : resolveRenderer(path, schema);
    };
  }
  return env;
}

// 处理scheme的相关方法
export const schemaUtil = {
  getKey() {
    return `${udp.getQueryValue('busType') || 'dev'}_scheme`;
  },
  setData(value: any) {
    udp.setCache(this.getKey(), value);
  },
  getData({ cache = true, schema = [], pageType = 'container' }: { cache?: boolean, schema?: any[], pageType?: 'container' | 'page' } = {}): { value: any, packages?: Record<string, any> } {
    const dv = {
      type: pageType,
      name: pageType,
      style: { backgroundColor: 'var(--body-background, #f0f2f5)' },
      size: 'sm',
      body: [
        ...schema,
      ],
    };
    const schemaValue = cache ? (udp.getCache(this.getKey(), { toObject: true }) || dv) : dv;
    return { value: schemaValue, packages: schemaValue?.amisPackages };
  },
  loadJsContent(source: string) {
    if (source) {
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.text = source;
      document.head.appendChild(script);
      return () => document.head.removeChild(script);
    }
    return () => void 0;
  },
};

export function arrayToOptions(arr: Array<string | { value: number | string; label: string }>, { inherit = false }: { inherit?: boolean } = {}) {
  const options = arr.map((value) => (isValueLabel(value) ? value : { value, label: value }));
  inherit && options.unshift({ value: '', label: '继承' });
  return options;
}

export function isValueLabel(val: any) {
  if (val) {
    return val.hasOwnProperty('value') && val.hasOwnProperty('label');
  }
  return false;
}

export function setTableColumnFormat(col: any, config?: any) {
  config = config || col;
  if (config.xtype === 'DatePicker' || config.type === 'udp-date-picker') {
    col.format = config.format || {
      type: 'date',
      formatter: 'YYYY-MM-DD'
    };
  }
  if (config.xtype === 'DateTimePicker' || (config.type === 'udp-date-picker' && config.showTime)) {
    col.format = config.format || {
      type: 'date',
      formatter: 'YYYY-MM-DD HH:mm:ss'
    };
  }
  if (config.options) {
    col.format = config.format || { type: 'option', formatter: config.options };
  }
  if (!config.editor && !config.dataIndexField && !col.format) {
    if (config.nameField) {
      col.dataIndexField = config.nameField;
    } else if (['Select', 'CheckboxGroup', 'RadioGroup', 'Switch'].includes(config.xtype) || config.xtype?.endsWith?.('Help')) {
      col.dataIndexField = `${col.dataIndex || col.name}EXName`;
    }
  }
}
